package com.csjbot.snowbot_rogue.servers.serials;


import com.csjbot.csjbase.log.Csjlogger;
import com.csjbot.snowbot_rogue.Events.HWTestEvent;
import com.csjbot.snowbot_rogue.app.RogueApp;
import com.csjbot.snowbot_rogue.utils.NetDataTypeTransform;
import com.upcontrol.uartagent.BodyUartAgent;
import com.upcontrol.uartagent.constant.ClientConstant;
import com.upcontrol.uartagent.constant.UartCmdType;
import com.upcontrol.uartagent.entity.RespMotorSpeedPacket;
import com.upcontrol.uartagent.entity.RespSelfCheckPacket;
import com.upcontrol.uartagent.entity.SNGetPacket;
import com.upcontrol.uartagent.entity.UartPacket;
import com.upcontrol.uartagent.listener.ClientEvent;
import com.upcontrol.uartagent.listener.EventListener;
import com.upcontrol.uartagent.utils.PacketBuilder;

import org.greenrobot.eventbus.EventBus;

/**
 * Created by Administrator on 2016/7/11 0011.
 */
public class SnowBotSerialServer implements SnowBotAction {

    private static SnowBotSerialServer ourInstance = new SnowBotSerialServer();
    private SnowBotSerialListener botListener;
    private BodyUartAgent agent;
    private EventBus iBus;

    public static SnowBotSerialServer getOurInstance() {
        return ourInstance;
    }

    private SnowBotSerialServer() {
//        BodyUartAgent.setEmUartAgentType(EmUartAgentType.emUsb2Uartagent);
        agent = BodyUartAgent.createBodyUartAgent(RogueApp.getAppContext(), "/dev/ttyS1", 115200, new EventListener() {
            @Override
            public void onEvent(ClientEvent event) {
                switch (event.eventType) {
                    case ClientConstant.EVENT_PACKET:
                        processPacket((UartPacket) event.data, botListener);
                        break;
                    case ClientConstant.EVENT_CONNECT_SUCCESS:
//                        Csjlogger.error("ClientConstant.EVENT_CONNECT_SUCCESS");
                        break;
                    case ClientConstant.SEND_FAILED:
                        Csjlogger.warn("UpBody uart send failed, reason is {}", (int) event.data);
                        break;
                    default:
                        break;
                }
            }
        });
        iBus = EventBus.getDefault();
    }

    private void processPacket(UartPacket packet, SnowBotSerialListener botListener) {
        if (botListener == null)
            return;
        switch (packet.getCmd()) {
            case UartCmdType.RecFromUart.SENSOR_TOUCH:
                botListener.touchedGet();
                break;
            case UartCmdType.RecFromUart.SENSOR_TEMPERATURE_HUMIDITY:
                if (packet.getContent().length == 2) {
                    botListener.temperature_humidityGet(packet.getContent()[0], packet.getContent()[1]);
                }
                break;
            case UartCmdType.RecFromUart.SENSOR_PM2_5:
                if (packet.getContent().length == 2) {
                    botListener.PM25Get(NetDataTypeTransform.bytesToShort(packet.getContent(), 0));
                }
                break;
            case UartCmdType.RecFromUart.SENSOR_COMBUSTIBLE_GAS:
                botListener.combustiblegasGet();
                break;
            case UartCmdType.RecFromUart.SNOWBOT_UPBODY_SN: {
                SNGetPacket snGetPacket = (SNGetPacket) packet;
                botListener.UpBodySNGet(snGetPacket.getSN());
            }
            break;
            case UartCmdType.RecFromUart.SNOWBOT_DOWNBODY_SN: {
                SNGetPacket snGetPacket = (SNGetPacket) packet;
                botListener.DownBodySNGet(snGetPacket.getSN());
            }
            break;
            case UartCmdType.RecFromUart.SNOWBOTOFF:
                botListener.snowBotOff();
                break;
            case UartCmdType.RecFromUart.FAULT:
                if (packet.getContent().length == 2) {
                    botListener.faultyGet(packet.getContent()[0], packet.getContent()[1]);
                }
                break;
            case UartCmdType.RecFromUart.UPBODY_SELF_CHECK: {
                RespSelfCheckPacket selfCheckPacket = (RespSelfCheckPacket) packet;
                botListener.upBodySelfChecked(selfCheckPacket.getHardWareState());
            }
            break;
            case UartCmdType.RecFromUart.DOWNBODY_SELF_CHECK: {
                RespSelfCheckPacket selfCheckPacket = (RespSelfCheckPacket) packet;
                botListener.downBodySelfChecked(selfCheckPacket.getHardWareState());
            }
//                RequireUpBodyCheckPacket hardWareSelfCheckPacket = (RequireUpBodyCheckPacket) packet;
//                botListener.upBodySelfChecked(hardWareSelfCheckPacket.getHardWareState());
            break;

            //0xA9 获取电机速度数据
            case UartCmdType.RecFromUart.RESP_MOTOR_SPEED: {
                RespMotorSpeedPacket motoSpeedPacket = (RespMotorSpeedPacket) packet;
                iBus.post(new HWTestEvent(1, "轮子速度 " + motoSpeedPacket.getMotorSpeed(),motoSpeedPacket.getSpeedIntArray()));
            }
            break;
            default:
                break;
        }
    }

    public void setBotListener(SnowBotSerialListener listener) {
        this.botListener = listener;
    }

    /**
     * 左手臂摆动
     * <p/>
     *
     * @param number 手臂摆动次数
     */
    @Override
    public void swingLeftArm(byte number) {
        agent.sendMessage(PacketBuilder.createShakeHandPacket(UartCmdType.SendToUart.ARM_LEFT, number));
    }

    /**
     * 右手臂摆动
     * <p/>
     *
     * @param number 手臂摆动次数
     */
    @Override
    public void swingRightArm(byte number) {
        agent.sendMessage(PacketBuilder.createShakeHandPacket(UartCmdType.SendToUart.ARM_RIGHT, number));
    }

    /**
     * 双臂摆动
     * <p/>
     *
     * @param number 手臂摆动次数
     */
    @Override
    public void swingDoubleArm(byte number) {
        agent.sendMessage(PacketBuilder.createShakeHandPacket(UartCmdType.SendToUart.ARM_DOUBLE, number));
    }

    /**
     * 开启传感器
     * <p/>
     *
     * @param sensorType 传感器类型
     */
    @Override
    public void turnOnSensor(byte sensorType) {
        agent.sendMessage(PacketBuilder.createSensorSwitchPacket(UartCmdType.SendToUart.SENSOR_OPEN, sensorType));
    }

    /**
     * 关闭传感器
     * <p/>
     *
     * @param sensorType 传感器类型
     */
    @Override
    public void turnOffSensor(byte sensorType) {
        agent.sendMessage(PacketBuilder.createSensorSwitchPacket(UartCmdType.SendToUart.SENSOR_OFF, sensorType));
    }

    @Override
    public void requireSend(byte sensorType) {
        agent.sendMessage(PacketBuilder.createSensorRequirePacket(sensorType));
    }


    /**
     * 所有的传感器数据开始发送
     * <p/>
     */
    @Override
    public void requireAllSensor() {
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                requireSend(UartCmdType.SendToUart.SENSOR_TYPE_TEMPERATURE_HUMIDITY);
//
//                try {
//                    Thread.sleep(100);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//                requireSend(UartCmdType.SendToUart.SENSOR_TYPE_PM25);
//
//                try {
//                    Thread.sleep(100);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//                requireSend(UartCmdType.SendToUart.SENSOR_TYPE_COMBUSTIBLE_GAS);
//            }
//        }).start();
    }

    /**
     * 获取机器人的SN
     */
    @Override
    public void getRobotSN() {
        agent.sendMessage(PacketBuilder.createRequireUpBodySNPacket());
    }

    @Override
    public void snowBotOff() {
        agent.sendMessage(PacketBuilder.createRobotOffPacket());
    }

    @Override
    public void getRobotDownSN() {
        agent.sendMessage(PacketBuilder.createRequireDownBodySNPacket());
    }

    @Override
    public void requireSelfCheck() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                agent.sendMessage(PacketBuilder.createRequireUpBodyCheckPacket());
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                agent.sendMessage(PacketBuilder.createRequireDownBodyCheckPacket());
            }
        }).start();

    }

}
